<?php

namespace app\api\controller;

use app\api\BaseController;
use app\api\middleware\Auth;
use think\Exception;
use think\facade\Db;
use think\facade\Request;
use think\response\Json;

/**
 *  公共方法文件
 */
class Common extends BaseController
{
    /**
     * 免登录方法
     * 控制器中间件 [登录 不需要鉴权]
     * @var array
     */
    protected $middleware = [
        Auth::class => ['except' => []]
    ];



    /**
     * 签名base64
     * base64 文件上传
     */
    public function base64_upload()
    {
        $base64Image = Request::post('file');
        try {
            if (empty($base64Image)) {
                throw new Exception('请先上传文件');
            }
            // 验证 base64 图片数据的合法性
            if (!preg_match('/^data:image\/(.*?);base64/', $base64Image)) {
                throw new Exception('无效的 base64 图片数据');
            }
            $base64Image = substr($base64Image, '22');
            // 解码base64文件数据
            $decodedImage = base64_decode($base64Image);;
            $filename = uniqid() . '.png';
            $storagePath = app()->getRootPath() . 'public/storage/base64_image';
            $file = $storagePath . '/' . $filename;
            file_put_contents($file, $decodedImage);
            return to_assign(1, '请求成功', ['url' => 'storage/base64_image/' . $filename]);
        } catch (Exception $e) {
            return to_assign(0, $e->getMessage());
        }

    }


    /**
     * 文件上传
     * @return Json
     */
    public function upload(): Json
    {
        $param = get_params();
        $sourse = isset($param['source']) ? $param['sourse'] : 'file';

        if ($sourse == 'file' || $sourse == 'tinymce') {
            $file = request()->file('file');
        } else {
            $file = request()->file('editormd-image-file');
        }

        if (!$file) {
            return to_assign(1, '没有选择上传文件');
        }

        $validateResult = $this->validateFile($file, $param);
        if ($validateResult !== true) {
            return to_assign(1, $validateResult);
        }
        $md5 = $file->hash('md5');
        $filename = $this->uploadFile($file , $md5);
        if (!$filename) {
            return to_assign(1, '上传失败，请重试');
        }

        $data = $this->prepareAttachmentData($file, $filename, $md5);
        $res = $this->writeToAttachmentTable($data);

        if ($sourse == 'editormd') {
            return json(['success' => 1, 'message' => '上传成功', 'url' => $data['filepath']]);
        } elseif ($sourse == 'tinymce') {
            return json(['success' => 1, 'message' => '上传成功', 'location' => $data['filepath']]);
        } else {
            return to_assign(0, '上传成功', $res);
        }
    }

    private function validateFile($file, $param)
    {
        $rule = [
            'image' => 'jpg,png,jpeg,gif',
            'doc' => 'txt,doc,docx,ppt,pptx,xls,xlsx,pdf',
            'file' => 'zip,gz,7z,rar,tar',
            'video' => 'mpg,mp4,mpeg,avi,wmv,mov,flv,m4v',
        ];

        $fileExt = $rule['image'] . ',' . $rule['doc'] . ',' . $rule['file'] . ',' . $rule['video'];
        $fileSize = 100 * 1024 * 1024;

        if (isset($param['type']) && $param['type']) {
            $fileExt = $rule[$param['type']];
        }

        if (isset($param['size']) && $param['size']) {
            $fileSize = $param['size'];
        }

        $validate = \think\facade\Validate::rule([
            'image' => 'require|fileSize:' . $fileSize . '|fileExt:' . $fileExt,
        ]);

        $file_check['image'] = $file;

        if (!$validate->check($file_check)) {
            return $validate->getError();
        }

        return true;
    }

    private function uploadFile($file,$md5)
    {

        $dataPath = date('Ym');
        return \think\facade\Filesystem::disk('public')->putFile($dataPath, $file, function () use ($md5) {
            return $md5;
        });
    }

    private function prepareAttachmentData($file, $filename, $md5): array
    {
        $sha1 = $file->hash('sha1');
        $path = get_config('filesystem.disks.public.url');

        $data = [
            'filepath' => $path . '/' . $filename,
            'name' => $file->getOriginalName(),
            'mimetype' => $file->getOriginalMime(),
            'fileext' => $file->extension(),
            'filesize' => $file->getSize(),
            'filename' => $filename,
            'sha1' => $sha1,
            'md5' => $md5,
            'module' => \think\facade\App::initialize()->http->getName(),
            'action' => app('request')->action(),
            'uploadip' => app('request')->ip(),
            'create_time' => time(),
            'user_id' => $this->uid,
        ];

        if ($data['module'] == 'admin') {
            $data['status'] = 1;
            $data['admin_id'] = $data['user_id'];
            $data['audit_time'] = time();
        }

        $data['use'] = request()->has('use') ? request()->param('use') : 'thumb';

        return $data;
    }

    private function writeToAttachmentTable($data): array
    {
        $res['id'] = Db::name('file')->insertGetId($data);
        $res['filepath'] = $data['filepath'];
        $res['name'] = $data['name'];
        $res['filename'] = $data['filename'];
        $res['filesize'] = $data['filesize'];
        $res['fileext'] = $data['fileext'];

        add_log('upload', $data['user_id'], $data, '文件');

        return $res;
    }

}

